package basic.arch.component.lock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import basic.arch.component.lock.config.CurrentLockSettings;
import basic.arch.component.lock.distributed.DistributionLock;
import basic.arch.component.lock.distributed.DistributionLockResult;
import basic.arch.component.lock.distributed.DistributionLockSpringApplicationContextHolder;
import basic.arch.component.lock.distributed.DistributionLockSupport;
import basic.arch.component.lock.local.LocalLock;
import basic.arch.component.lock.local.LocalLockResult;
import basic.arch.component.lock.local.LockSettings;

@Component
public class LockFacadeImpl implements LockFacade, InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(LockFacadeImpl.class);
    private LocalLock localLock;

    @Autowired
    private LockSettings lockSettings;

    @Override
    public void afterPropertiesSet() throws Exception {
        localLock = new LocalLock(lockSettings);
    }

    public void unlock(LockDetail lockDetail) {
        
        if (lockDetail != null && lockDetail.getDistributionLockResult().isDistributionLockSuccess()) {
            DistributionLock distributionLock = DistributionLockSpringApplicationContextHolder.getDistributionLock(lockDetail.getLocalLockResult().getCurrentLockSettings().getDisstributionLockType());
            distributionLock.unlock(lockDetail.getLocalLockResult().getCurrentLockSettings().getCurrenLockKey());
        }
        if (lockDetail != null && lockDetail.getLocalLockResult().isLocalLockSuccess()) {
            localLock.unlock(lockDetail.getLocalLockResult());
        }
    }

    public LockDetail acquireLock(CurrentLockSettings currentLockSettings) {
        LockDetail lockDetail = new LockDetail();
        // 现获取本地锁
        LocalLockResult localLockResult = localLock.tryLock(currentLockSettings);
        lockDetail.setLocalLockResult(localLockResult);
        // 如果本地锁获取成功
        if (localLockResult.isLocalLockSuccess()) {
            currentLockSettings.setDistributionLockMaxWaitTime(currentLockSettings.getDistributionLockMaxWaitTime());
            DistributionLock distributionLock = DistributionLockSpringApplicationContextHolder.getDistributionLock(lockDetail.getLocalLockResult().getCurrentLockSettings().getDisstributionLockType());
            distributionLock.tryLock(currentLockSettings);
            DistributionLockResult distributionLockResult = DistributionLockSupport.distributionLockResultThreadLocal.get();
            lockDetail.setDistributionLockResult(distributionLockResult);
        } else {
            LOGGER.error("key:{},本地锁获取失败,不再获取分布式锁", currentLockSettings.getCurrenLockKey());
        }
        return lockDetail;
    }
    
    

   

}
